<?php
session_start();

class Home extends CI_Controller
{
	public function __construct()
	{
		parent::__construct();
		$this->load->model('roles');
		$this->load->model('users');
		$this->load->model('environment');
		$this->data['title'] = 'SEVA Sports';
		$this->data['base'] = $this->config->item('base_url');
		$this->data['css'] = $this->data['base'].$this->config->item('css');
		$this->data['images'] = $this->data['base'].$this->config->item('images');
		$this->data['js'] = $this->data['base'].$this->config->item('js');
	}
	
	public function forgot_password()
	{
		$this->load->library('form_validation');
		if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->validate__send_temporary_password())
		{
			$this->environment->send_temporary_password($_POST['email']);
			return;
		}
		$this->data['head']['css'] = array('main.css');
		$this->load->view('templates/header', $this->data);
		$this->load->view('home/forgot_password', $this->data);
		$this->load->view('templates/footer', $this->data);
	}
	
	public function index()
	{
		$this->load->library('form_validation');
		if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->validate__signup())
		{
			$this->load->helper('url');
			
			// Log the new user in.
			$_SESSION['id'] = $this->users->insert(
				$_POST['name'],
				$_POST['email'],
				$_POST['password'],
				$_POST['role'],
				$_POST['school'],
				$_POST['city'],
				$_POST['state']
			);
			
			// Redirect the new user to the correct profile page.
			$role = $this->roles->select_by_user_id($_SESSION['id']);
			redirect($role->redirect_url);
			return;
		}
		$this->data['head']['css'] = array('main.css');
		$this->data['roles'] = $this->roles->select_by_names(
			array('College Coach', 'High School Coach', 'High School Player')
		);
		$this->load->view('templates/header', $this->data);
		$this->load->view('home/index', $this->data);
		$this->load->view('templates/footer', $this->data);
	}
	
	public function login()
	{
		$this->load->helper('url');
		
		// The user cannot access this page while he or she is already logged in.
		if (isset($_SESSION['id']))
		{
			redirect('/');
		}
		
		// If the user enters a matching email and password, send the user to his or her profile page.
		if ($_SERVER['REQUEST_METHOD'] == 'POST')
		{
			$user = $this->users->authenticate($_POST['email'], $_POST['password']);
			if ($user != null)
			{
				$_SESSION['id'] = $user->id;
				$role = $this->roles->select_by_user_id($user->id);
				redirect($role->redirect_url);
				return;
			}
			else
			{
				// If the user fails to log in, show an error message.
				$this->data['error'] = 'Incorrect email address or password';
			}
		}
		
		// If this code is reached, either this page was access via the GET method, or the user
		// failed to log in properly. The login form should be shown, along with any error
		// messages if applicable.
		$this->data['head']['css'] = array('main.css');
		$this->load->view('templates/header', $this->data);
		$this->load->view('home/login', $this->data);
		$this->load->view('templates/footer', $this->data);
	}
	
	public function logout()
	{
		$this->load->helper('url');
		unset($_SESSION['id']);
		redirect('/');
	}
	
	// ----------------- SERVER-SIDE VALIDATION FUNCTIONS ----------------- //
	
	/**
	 * Rules for validation (in order):
	 * 
	 * 1. All required fields must be filled in.
	 * 2. The email address must belong to a user's account.
	 * 
	 * @return True if the submitted form is valid; false otherwise.
	 */
	private function validate__send_temporary_password()
	{
		// 1. All required fields must be filled in.
		$this->form_validation->set_rules('email', 'An email address', 'required');
		$this->form_validation->set_message('required', '%s is required.');
		if (!$this->form_validation->run()) return false;
		
		// 2. The email address must belong to a user's account.
		$this->form_validation->set_rules('email', '', 'callback__email_exists[true]');
		$this->form_validation->set_message('_email_exists', 'The email address you entered cannot be found. Please try a different email address.');
		if (!$this->form_validation->run()) return false;
		
		// If this point has been reached, the validation passed.
		return true;
	}
	
	/**
	 * Rules for validation (in order):
	 * 
	 * 1. All required fields must be filled in.
	 * 2. The password must be between 8 and 32 characters and contain at least
	 *    one letter and one number.
	 * 3. The email address must not exist in the database.
	 * 4. The password and confirm-password fields must match.
	 * 
	 * @return True if the submitted form is valid; false otherwise.
	 */
	private function validate__signup()
	{
		// 1. All required fields must be filled in.
		$this->form_validation->set_rules('name', 'Your name', 'required');
		$this->form_validation->set_rules('school', 'Your school', 'required');
		$this->form_validation->set_rules('city', 'The city', 'required');
		$this->form_validation->set_rules('state', 'The state', 'required');
		$this->form_validation->set_rules('email', 'An email address', 'required');
		$this->form_validation->set_rules('password', 'The password', 'required');
		$this->form_validation->set_rules('password_confirm', 'The password confirmation', 'required');
		$this->form_validation->set_rules('role', 'role', 'callback__required2');
		$this->form_validation->set_message('required', '%s is required.');
		$this->form_validation->set_message('_required2', 'Please select a %s');
		if (!$this->form_validation->run()) return false;
		
		// 2. The password must be between 8 and 32 characters and contain at least
	 	//    one letter and one number. The answer to the security question must
	    //    be 32 characters or less.
		$this->form_validation->set_rules('password', 'The password', 'callback__password');
		$this->form_validation->set_message('_password', 'The password you entered is invalid.');
		if (!$this->form_validation->run()) return false;
		
		// 3. The email address must not exist in the database.
		$this->form_validation->set_rules('email', '', 'callback__email_exists['.false.']');
		$this->form_validation->set_message('_email_exists', 'The email address you entered is already taken. Please try a different email address.');
		if (!$this->form_validation->run()) return false;
		
		// 4. The password and confirm-password fields must match.
		$this->form_validation->set_rules('password_confirm', '', 'matches[password]');
		$this->form_validation->set_message('matches', 'The password and password confirmation must match.');
		if (!$this->form_validation->run()) return false;
		
		// If this point has been reached, the validation passed.
		return true;
	}
	
	/**
	 * Custom validation function that checks whether the given email address
	 * is already in the database for some user's account.
	 * 
	 * @param  $val    The email address
	 * @param  $exists The existence of the email address must evaluate to this
	 *                 in order for this validation function to return true.
	 * 
	 * @return True if the existence of the email address in the database
	 *         matches $exists; false otherwise.
	 */
	function _email_exists($val, $exists = true)
	{
		return $this->users->email_exists($val) == $exists;
	}
	
	/**
	 * Custom validation function that makes sure that an option from a
	 * dropdown menu or group of radio buttons is selected. If nothing is
	 * selected, then the validation should fail.
	 * 
	 * @param  The value of the selected option.
	 * @return True if a value was selected; false otherwise.
	 */
	function _required2($val)
	{
		return isset($val) and $val != '' and $val != '0';
	}
	
	/**
	 * Custom validation function for the password. The password must be
	 * between 8 and 32 characters and contain at least one number and one
	 * letter.
	 * 
	 * @param  The password the user entered.
	 * @return True if the password fits the above criteria; false otherwise.
	 */
	function _password($val)
	{
		$length = strlen($val);
		if ($length < 8 || $length > 32) return false;
		
		$result = 0;
		for ($i = 0; $i < $length && $result != 3; $i++)
		{
			if      (($result & 1) == 0 && ctype_alpha($val{$i})) $result |= 1;
			else if (($result & 2) == 0 && ctype_digit($val{$i})) $result |= 2;
		}
		
		return $result == 3;
	}
	
	public function test()
	{
		echo ($this->_email_exists('chriskoolest@yahoo.com', false) ? 'True' : 'False').'<br />';
		echo ($this->_email_exists('chriskoolest@yahoo.com', true) ? 'True' : 'False').'<br />';
	}
}